package code.Najib;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import client.domainModels.Node.Node;
import client.domainModels.NodeImpl.AbstractNode;
import client.domainModels.NodeImpl.LogFile;

public class CaseAgentNetDiscovery {

	private static ArrayList<String> agents = new ArrayList<String>();

	public static void caseAgentNet(LogFile log) {
		agents = new ArrayList<String>();
		int amountAgent = getAgentAmount(log);
		System.out.println(amountAgent);
		for (int i = 0; i < amountAgent; i++) {
			System.out.println(agents.get(i));
		}

		Integer[][] netDrawMatrix = new Integer[amountAgent][amountAgent];

		// initial the matrix
		for (int i = 0; i < amountAgent; i++) {
			for (int j = 0; j < amountAgent; j++) {
				netDrawMatrix[i][j] = 0;
			}
		}

		// analyse
		String[] nodes = log.getChildNodeNames();
		for (int i = 0; i < nodes.length; i++) {
			// name of root node's leaves nodes.
			String root_leaf = nodes[i];
			// get cases - root node's leaves nodes.
			ArrayList<AbstractNode> cases = log.getChildNodes(root_leaf);
			// iterate cases and get his leaves nodes'object.
			for (Iterator<AbstractNode> ii = cases.iterator(); ii.hasNext();) {
				// get each event - cases' leaves nodes object.
				Node case_ = ii.next();
				ArrayList<AbstractNode> events = case_.getChildNames_childObjs().get(
						"Event");
				for (Iterator<AbstractNode> iii = events.iterator(); iii.hasNext();) {
					Node event = iii.next();
					// get actor, receivers - event's leaves nodes.
					ArrayList<AbstractNode> actors = event.getChildNames_childObjs()
							.get("Actor");
					ArrayList<AbstractNode> receiverss = event
							.getChildNames_childObjs().get("Receivers");
					// The collection (agents) of actor and receivers is empty
					// or not

					// id of actor
					String actorID = actors.get(0).getID().toLowerCase();
					int indexOfActor = agents.indexOf(actorID);
					// add each receiver to the collection
					ArrayList<AbstractNode> receivers = receiverss.get(0)
							.getChildNames_childObjs().get("Receiver");
					for (Iterator<AbstractNode> iiii = receivers.iterator(); iiii
							.hasNext();) {
						Node receiver = iiii.next();
						String receiverName = receiver.getID().toLowerCase();
						if (!receiverName.equalsIgnoreCase("system")) {
							int indexOfReceiver = agents.indexOf(receiverName);
							netDrawMatrix[indexOfActor][indexOfReceiver] += 1;
							netDrawMatrix[indexOfReceiver][indexOfActor] += 1;
						}
					}
				}
			}
		}

		for (int i = 0; i < amountAgent; i++) {
			for (int j = 0; j < amountAgent; j++) {
				System.out.print(netDrawMatrix[i][j] + " ");
			}
			System.out.println();
		}

		createFileVNA(netDrawMatrix, "./same_case.vna");
                ActivityAgentNetDiscovery.createBatchFile("./batch_Case.txt","same_case.vna");
	}

	private static int getAgentAmount(LogFile log) {
		int agentAmount = 0;
		String[] nodes = log.getChildNodeNames();
		// Get leaves nodes of root node.
		for (int i = 0; i < nodes.length; i++) {
			// name of root node's leaves nodes.
			String root_leaf = nodes[i];
			// get cases - root node's leaves nodes.
			ArrayList<AbstractNode> cases = log.getChildNodes(root_leaf);
			// iterate cases and get his leaves nodes'object.
			for (Iterator<AbstractNode> ii = cases.iterator(); ii.hasNext();) {
				// get each event - cases' leaves nodes object.
				Node case_ = ii.next();
				ArrayList<AbstractNode> events = case_.getChildNames_childObjs().get(
						"Event");
				for (Iterator<AbstractNode> iii = events.iterator(); iii.hasNext();) {
					Node event = iii.next();
					// get actor, receivers - event's leaves nodes.
					ArrayList<AbstractNode> actors = event.getChildNames_childObjs()
							.get("Actor");
					ArrayList<AbstractNode> receiverss = event
							.getChildNames_childObjs().get("Receivers");
					// The collection (agents) of actor and receivers is empty
					// or
					// not
					String actorID = actors.get(0).getID().toLowerCase();
					if (agents.isEmpty()) {
						// add actor to the collection
						if (!actorID.equalsIgnoreCase("System"))
							agents.add(actorID.toLowerCase());
					} else {
						if (!agents.contains(actorID)) {
							if (!actorID.equalsIgnoreCase("System"))
								agents.add(actorID.toLowerCase());
						}
					}
					// add each receiver to the collection
					ArrayList<AbstractNode> receivers = receiverss.get(0)
							.getChildNames_childObjs().get("Receiver");
					for (Iterator<AbstractNode> iiii = receivers.iterator(); iiii
							.hasNext();) {
						Node receiver = iiii.next();
						String receiverName = receiver.getID().toLowerCase();
						if (!agents.contains(receiverName)) {
							if (!receiverName.equalsIgnoreCase("System"))
								agents.add(receiverName);
						}
					}
				}
			}
		}
		// create a matrix and the size of matrix is amount of agent * amount of
		// agent.
		agentAmount = agents.size();
		return agentAmount;
	}

	public static void createFileVNA(Integer[][] matrix, String filePath) {
		File pointVNA = new File(filePath);
		try {
			FileWriter fw = new FileWriter(pointVNA);
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write("*Node data" + "\n");
			bw.write("*Node properties" + "\n");
			bw.write("*Tie data" + "\n");
			bw.write("AGENT_A AGENT_B \"" + "Agents treating same case" + "\"" + "\n");
			for (int i = 0; i < matrix.length; i++) {
				for (int j = 0; j < matrix.length; j++) {
					if (matrix[i][j] != 0) {
						String actor = agents.get(i);
						String receiver = agents.get(j);
						bw.write("\"" + actor + "\"");
						bw.write(" ");
						bw.write("\"" + receiver + "\"");
						bw.write(" ");
						bw.write(""+matrix[i][j]+"");
						bw.write("\n");
					}
				}
			}
			bw.flush();
                        bw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
